#include "view_metronome.h"
#include "display_ctrl.h"
#include "platform_assert.h"
#include "lfs_file_manager_auto.h"
#include "rtc.h"
#include "datetime.h"
#include "blecom.h"
#include "battery_ctrl.h"
#include "sport_his.h"
#include "display_interface_240x240.h"
#include "datetime.h"
#include "heart_rate_interface.h"
#include "font/num_font.h"
#include "view_common.h"
#include "Motor.h"
#include "view.h"
#include "times/view_times.h"
#include "sports_mode.h"
#include "app_trace.h"
#include "app_timer.h"
#include "view_metronome.inc"
#define LOG(fmt, ...) app_trace_log(fmt "\r\n", ##__VA_ARGS__)

#ifdef NO_METRONOME_UI
#else
APP_TIMER_DEF(metronome_timer_id); //佩戴检测
APP_TIMER_DEF(metronome_timer_second_id);
typedef struct __metronome_instance_t
{
    bool is_init;
    int seconds;
    int bpm;
    bool is_shake;
    bool is_run;
    uint64_t count;
} metronome_instance_t;
static metronome_instance_t metronome_instance;

static void metronome_timer_second_handle(void *p_context)
{
    metronome_instance.seconds++;
}
static void metronome_timer_handle(void *p_context)
{
    metronome_instance.is_shake = !metronome_instance.is_shake;
    motor_start(100);
    metronome_instance.count++;
}

void view_metronome_base_display()
{
    if (disp_ctrl.loop_cnt == 0)
    {
        disp_ctrl.auto_refresh_time = 500;
    }
    int x = 83;
    int y = 28;
    img_gif_com_t const img_cfg = {
        .gif_count = 2,
        .img[0].x = x,
        .img[0].y = y,
        .img[0].sn = FILE_IMG_E201_beat_icon_1_83_28,
        .img[1].x = x,
        .img[1].y = y,
        .img[1].sn = FILE_IMG_E202_beat_icon_2_83_28,

    };
    _disp_show_flash_img_gif_all(&img_cfg, DISP_LFS_FILE_INDEX_0);
    // x = 67;
    // y = 156;
    // _disp_show_flash_img(DISP_LFS_FILE_INDEX_1, x, y, FILE_IMG_E203_beat_text_67_156);
    disp_show_localize(DISP_LFS_FILE_INDEX_1, localize_string_key_Metronome, 50);
}
#ifdef EVENT_PREVIOUS_VIEW
void view_metronome_set_display(void)
{
    int x = 25;
    int y = 0;
    _disp_show_flash_img(DISP_LFS_FILE_INDEX_0, x, y, FILE_IMG_E118_beat_set_25_0);
    disp_show_localize(DISP_LFS_FILE_INDEX_1, localize_string_key_metronomeOptionSetFrequency, 50);
    for (int i = 32; i < 32 + 176; i++)
    {
        disp_draw_point(i, 91, 0x3186);
        disp_draw_point(i, 162, 0x3186);
    }
    x = 173;
    y = 115;
    disp_draw_user_image(x, y, bmp_unit_bpm);

    int hundreds = disp_ctrl.com_data.i_temp[0] / 100;
    int tens = disp_ctrl.com_data.i_temp[0] / 10 % 10;
    int units = disp_ctrl.com_data.i_temp[0] % 10;
    y = 100;
    if (hundreds != 0)
    {
        x = 83;
        _disp_show_flash_img(DISP_LFS_FILE_INDEX_3, x, y, FILE_IMG_E101_beat_0 + hundreds);
    }
    if (tens != 0 || hundreds != 0)
    {
        x = 110;
        _disp_show_flash_img(DISP_LFS_FILE_INDEX_4, x, y, FILE_IMG_E101_beat_0 + tens);
    }
    x = 137;
    _disp_show_flash_img(DISP_LFS_FILE_INDEX_5, x, y, FILE_IMG_E101_beat_0 + units);
    if (disp_ctrl.com_data.i_temp[0] > 10)
    {
        x = 120;
        y = 59;
        disp_draw_user_image_num_mid_ignore(x, y, RGB565_COLOR_BLACK, disp_ctrl.com_data.i_temp[0] - 1, 10, num_9x22_TAB);
    }
    if (disp_ctrl.com_data.i_temp[0] < 240)
    {
        x = 120;
        y = 174;
        disp_draw_user_image_num_mid_ignore(x, y, RGB565_COLOR_BLACK, disp_ctrl.com_data.i_temp[0] + 1, 10, num_9x22_TAB);
    }
}
void view_metronome_state_display(void)
{
    if (disp_ctrl.loop_cnt == 0)
    {
        disp_ctrl.com_data.i_temp[0] = metronome_instance.seconds;
        disp_ctrl.com_data.i_temp[1] = metronome_instance.is_run;
        disp_ctrl.com_data.i_temp[2] = metronome_instance.bpm;
        disp_ctrl.com_data.i_temp[3] = metronome_instance.is_shake;
        if (disp_ctrl.com_data.i_temp[3] == disp_ctrl.com_data.i_temp[6] && disp_ctrl.com_data.i_temp[5] != metronome_instance.count)
        {
            //!< count不一样了，但是is_shake还是跟之前的一样，那么我也要假装不一样
            disp_ctrl.com_data.i_temp[3] = !disp_ctrl.com_data.i_temp[3];
        }
        disp_ctrl.com_data.i_temp[5] = metronome_instance.count;
        disp_ctrl.com_data.i_temp[6] = disp_ctrl.com_data.i_temp[3];
        disp_ctrl.auto_refresh_time = 0;
        int rtc_time = rtc_get_utc();
        if (disp_ctrl.com_data.i_temp[4] != rtc_time)
        {
            disp_ctrl.area_update_flag = 0;
        }
        else
        {
            display_set_update_area(54, 40, 17, 17);
        }
        disp_ctrl.com_data.i_temp[4] = rtc_time;
    }
    int x = 23;
    int y = 90;
    _disp_show_flash_img(DISP_LFS_FILE_INDEX_0, x, y, FILE_IMG_E114_frame_23_90);
    x = 179;
    y = 110;
    if (disp_ctrl.com_data.i_temp[1])
    {
        _disp_show_flash_img(DISP_LFS_FILE_INDEX_1, x, y, FILE_IMG_E116_beat_end_179_110);
    }
    else
    {
        _disp_show_flash_img(DISP_LFS_FILE_INDEX_1, x, y, FILE_IMG_E115_beat_start_179_110);
    }
    x = 81;
    y = 116;
    disp_draw_rect_color(x, y, x + 4, y + 4, RGB565_COLOR_WHITE);
    x = 81;
    y = 132;
    disp_draw_rect_color(x, y, x + 4, y + 4, RGB565_COLOR_WHITE);
    x = 128;
    y = 116;
    disp_draw_rect_color(x, y, x + 4, y + 4, RGB565_COLOR_WHITE);
    x = 128;
    y = 132;
    disp_draw_rect_color(x, y, x + 4, y + 4, RGB565_COLOR_WHITE);
    int hour = disp_ctrl.com_data.i_temp[0] / 60 / 60 % 99;
    int min = disp_ctrl.com_data.i_temp[0] / 60 % 60;
    int second = disp_ctrl.com_data.i_temp[0] % 60;
    x = 43;
    y = 102;
    disp_draw_user_image_num_with_digits(x, y, hour, 2, 18, num_15x37_TAB);
    x = 90;
    disp_draw_user_image_num_with_digits(x, y, min, 2, 18, num_15x37_TAB);
    x = 136;
    disp_draw_user_image_num_with_digits(x, y, second, 2, 18, num_15x37_TAB);
    x = 54;
    y = 40;
    if (disp_ctrl.com_data.i_temp[3])
    {
        disp_draw_user_image(x, y, bmp_shakeing);
    }
    else
    {
        disp_draw_user_image(x, y, bmp_shake_idle);
    }
    int max_width = 25 * 3 + 2 + 31;
    int digit = get_num_digit(disp_ctrl.com_data.i_temp[2]);
    int show_width = 25 * digit + 2 + 31;
    x = 83 + (max_width - show_width) / 2;
    y = 21;
    _disp_show_flash_img(DISP_LFS_FILE_INDEX_3, x, y, FILE_IMG_E101_beat_0 + disp_ctrl.com_data.i_temp[2] / 100);
    x += 25;
    _disp_show_flash_img(DISP_LFS_FILE_INDEX_4, x, y, FILE_IMG_E101_beat_0 + (disp_ctrl.com_data.i_temp[2] / 10) % 10);
    x += 25;
    _disp_show_flash_img(DISP_LFS_FILE_INDEX_5, x, y, FILE_IMG_E101_beat_0 + disp_ctrl.com_data.i_temp[2] % 10);
    x += 25 + 2;
    y = y + 52 - 18;
    disp_draw_user_image(x, y, bmp_unit_bpm);
    x = 20;
    y = 166;
    _disp_show_flash_img(DISP_LFS_FILE_INDEX_2, x, y, FILE_IMG_E117_beat_set_20_166_);
    disp_show_localize(DISP_LFS_FILE_INDEX_6, localize_string_key_metronomeBaseSetFrequency, 50);
}
#else  //!<#ifdef EVENT_PREVIOUS_VIEW
void view_metronome_state_display(void)
{
    if (disp_ctrl.loop_cnt == 0)
    {
        disp_ctrl.com_data.i_temp[0] = metronome_instance.seconds;
        disp_ctrl.com_data.i_temp[1] = metronome_instance.is_run;
        disp_ctrl.com_data.i_temp[2] = metronome_instance.bpm;
        disp_ctrl.com_data.i_temp[3] = metronome_instance.is_shake;
        if (disp_ctrl.com_data.i_temp[3] == disp_ctrl.com_data.i_temp[6] && disp_ctrl.com_data.i_temp[5] != metronome_instance.count)
        {
            //!< count不一样了，但是is_shake还是跟之前的一样，那么我也要假装不一样
            disp_ctrl.com_data.i_temp[3] = !disp_ctrl.com_data.i_temp[3];
        }
        disp_ctrl.com_data.i_temp[5] = metronome_instance.count;
        disp_ctrl.com_data.i_temp[6] = disp_ctrl.com_data.i_temp[3];
        disp_ctrl.auto_refresh_time = 0;
        int rtc_time = rtc_get_utc();
        if (disp_ctrl.com_data.i_temp[4] != rtc_time)
        {
            disp_ctrl.area_update_flag = 0;
        }
        else
        {
            display_set_update_area(54, 40, 17, 17);
        }
        disp_ctrl.com_data.i_temp[4] = rtc_time;
    }
    int x = 23;
    int y = 90;
    _disp_show_flash_img(DISP_LFS_FILE_INDEX_0, x, y, FILE_IMG_E114_frame_23_90);
    x = 116;
    y = 173;
    if (disp_ctrl.com_data.i_temp[1])
    {
        _disp_show_flash_img(DISP_LFS_FILE_INDEX_1, x, y, FILE_IMG_E116_beat_end_179_110);
    }
    else
    {
        _disp_show_flash_img(DISP_LFS_FILE_INDEX_1, x, y, FILE_IMG_E115_beat_start_179_110);
    }
    x = 95;
    y = 122 - 6;
    disp_draw_rect_color(x, y, x + 4, y + 4, RGB565_COLOR_WHITE);
    x = 95;
    y = 138 - 6;
    disp_draw_rect_color(x, y, x + 4, y + 4, RGB565_COLOR_WHITE);
    x = 141;
    y = 122 - 6;
    disp_draw_rect_color(x, y, x + 4, y + 4, RGB565_COLOR_WHITE);
    x = 141;
    y = 138 - 6;
    disp_draw_rect_color(x, y, x + 4, y + 4, RGB565_COLOR_WHITE);
    int hour = disp_ctrl.com_data.i_temp[0] / 60 / 60 % 99;
    int min = disp_ctrl.com_data.i_temp[0] / 60 % 60;
    int second = disp_ctrl.com_data.i_temp[0] % 60;
    x = 57;
    y = 107 - 6;
    disp_draw_user_image_num_with_digits(x, y, hour, 2, 18, num_15x37_TAB);
    x = 104;
    disp_draw_user_image_num_with_digits(x, y, min, 2, 18, num_15x37_TAB);
    x = 150;
    disp_draw_user_image_num_with_digits(x, y, second, 2, 18, num_15x37_TAB);
    x = 54;
    y = 40;
    if (disp_ctrl.com_data.i_temp[3])
    {
        disp_draw_user_image(x, y, bmp_shakeing);
    }
    else
    {
        disp_draw_user_image(x, y, bmp_shake_idle);
    }
    int max_width = 25 * 3 + 2 + 31;
    int digit = get_num_digit(disp_ctrl.com_data.i_temp[2]);
    int show_width = 25 * digit + 2 + 31;
    x = 83 + (max_width - show_width) / 2;
    y = 21;
    _disp_show_flash_img(DISP_LFS_FILE_INDEX_3, x, y, FILE_IMG_E101_beat_0 + disp_ctrl.com_data.i_temp[2] / 100);
    x += 25;
    _disp_show_flash_img(DISP_LFS_FILE_INDEX_4, x, y, FILE_IMG_E101_beat_0 + (disp_ctrl.com_data.i_temp[2] / 10) % 10);
    x += 25;
    _disp_show_flash_img(DISP_LFS_FILE_INDEX_5, x, y, FILE_IMG_E101_beat_0 + disp_ctrl.com_data.i_temp[2] % 10);
    x += 25 + 2;
    y = y + 52 - 18;
    disp_draw_user_image(x, y, bmp_unit_bpm);
}
#endif //!< #ifdef EVENT_PREVIOUS_VIEW
void view_metronome_display(int view)
{
    switch (view)
    {
    case view_metronome_base:
        view_metronome_base_display();
        break;
    case view_metronome_state:
        view_metronome_state_display();
        break;
#ifdef EVENT_PREVIOUS_VIEW
    case view_metronome_set:
        view_metronome_set_display();
        break;
#endif
    }
}
#ifdef EVENT_PREVIOUS_VIEW
void metronome_rest(void)
{
    if (metronome_instance.is_run)
    {
        metronome_instance.is_run = false;
        app_timer_stop(metronome_timer_id);
        app_timer_stop(metronome_timer_second_id);
    }
    metronome_instance.seconds = 0;
    metronome_instance.count = 0;
    display_set_update_request(view_metronome_state, 0);
}

view_event_result_t view_metronome_set_event(event_param_t const *param)
{
    switch (param->event)
    {
    case event_view_entry:
        disp_ctrl.com_data.i_temp[0] = get_metronome_hz();
        return view_event_result_handled;
#ifdef EVENT_PREVIOUS_VIEW
    case event_move_previous_view:
        if (disp_ctrl.com_data.i_temp[0] > 10)
        {
            disp_ctrl.com_data.i_temp[0]--;
            display_set_update_request(view_metronome_set, 0);
        }
        return view_event_result_handled;
#endif
#ifdef EVENT_NEXT_VIEW
    case event_move_next_view:
        if (disp_ctrl.com_data.i_temp[0] < 240)
        {
            disp_ctrl.com_data.i_temp[0]++;
            display_set_update_request(view_metronome_set, 0);
        }
        return view_event_result_handled;
#endif
#ifdef EVENT_BUTTON_FRONT
    case event_button_front_press:
        return view_event_result_handled;
#endif
#ifdef EVENT_BUTTON_FRONT
    case event_button_front_long_press:
#endif
#ifdef EVENT_LEVEL_UP
    case event_move_level_up:
#endif
        display_show(view_metronome_state, DISP_MODE_NORMAL);
        return view_event_result_handled;
#ifdef EVENT_LEVEL_DOWN
    case event_move_level_down:
        set_metronome_hz(disp_ctrl.com_data.i_temp[0]);
        display_show(view_metronome_state, DISP_MODE_NORMAL);
        return view_event_result_handled;
#endif
    case BUTTON_EVENT_LONG_PRESS:
    case BUTTON_EVENT_LONG_PRESS_KEEP:
        switch (param->source)
        {
        case event_source_button_up:
            LOG("metronome +10");
            if (disp_ctrl.com_data.i_temp[0] > 20)
            {
                disp_ctrl.com_data.i_temp[0] -= 10;
                display_set_update_request(view_metronome_set, 0);
            }
            else if (disp_ctrl.com_data.i_temp[0] > 10)
            {
                disp_ctrl.com_data.i_temp[0] = 10;
                display_set_update_request(view_metronome_set, 0);
            }
            return view_event_result_handled;
        case event_source_button_down:
            LOG("metronome -10");
            if (disp_ctrl.com_data.i_temp[0] < 230)
            {
                disp_ctrl.com_data.i_temp[0] += 10;
                display_set_update_request(view_metronome_set, 0);
            }
            else if (disp_ctrl.com_data.i_temp[0] < 240)
            {
                disp_ctrl.com_data.i_temp[0] = 240;
                display_set_update_request(view_metronome_set, 0);
            }
            return view_event_result_handled;
        }
        break;
    }
    return view_event_result_not_handled;
}
view_event_result_t view_metronome_state_event(event_param_t const *param)
{
    switch (param->event)
    {
    case event_view_entry:
        if (!metronome_instance.is_init)
        {
            metronome_instance.is_init = true;
            uint32_t err_code = app_timer_create(&metronome_timer_id, APP_TIMER_MODE_REPEATED, &metronome_timer_handle);
            Expects(err_code == NRF_SUCCESS);
            err_code = app_timer_create(&metronome_timer_second_id, APP_TIMER_MODE_REPEATED, &metronome_timer_second_handle);
            Expects(err_code == NRF_SUCCESS);
        }
        if (param->previous_view != view_metronome_state)
        {
            if (param->previous_view != view_metronome_set)
            {
                metronome_instance.seconds = 0;
                metronome_instance.count = 0;
            }
            metronome_instance.bpm = get_metronome_hz();
            metronome_instance.is_shake = false;
            metronome_instance.is_run = false;
        }
        return view_event_result_handled;
    case event_view_exit:
        app_timer_stop(metronome_timer_id);
        app_timer_stop(metronome_timer_second_id);
        return view_event_result_handled;
    case event_set_metronome:
        metronome_instance.bpm = param->hz;
        if (metronome_instance.is_run)
        {
            app_timer_stop(metronome_timer_id);
            app_timer_stop(metronome_timer_second_id);
            app_timer_start(metronome_timer_id, APP_TIMER_TICKS(1000 * 60 / metronome_instance.bpm, APP_TIMER_PRESCALER), 0);
            app_timer_start(metronome_timer_second_id, APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER), 0);
        }
        display_set_update_request(view_metronome_state, 0);
        return view_event_result_handled;
#ifdef EVENT_NEXT_VIEW
    case event_move_next_view:
#endif
        display_show(view_metronome_set, DISP_MODE_NORMAL);
        return view_event_result_handled;
#ifdef EVENT_BUTTON_FRONT
    case event_button_front_press:
#endif
#ifdef EVENT_LEVEL_DOWN
    case event_move_level_down:
#endif
        metronome_instance.is_run = !metronome_instance.is_run;
        if (metronome_instance.is_run)
        {
            app_timer_start(metronome_timer_id, APP_TIMER_TICKS(1000 * 60 / metronome_instance.bpm, APP_TIMER_PRESCALER), 0);
            app_timer_start(metronome_timer_second_id, APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER), 0);
        }
        else
        {
            app_timer_stop(metronome_timer_id);
            app_timer_stop(metronome_timer_second_id);
        }
        display_set_update_request(view_metronome_state, 0);
        return view_event_result_handled;
#ifdef EVENT_LEVEL_UP
    case event_move_level_up:
        display_show(view_metronome, DISP_MODE_NORMAL);
        return view_event_result_handled;
#endif
#ifdef EVENT_PREVIOUS_VIEW
    case event_move_previous_view:
        return view_event_result_handled;
#endif
#ifdef EVENT_BUTTON_FRONT
    case event_button_front_long_press:
#endif
        metronome_rest();
        return view_event_result_handled;
    case BUTTON_EVENT_LONG_PRESS:
        switch (param->source)
        {
        case event_source_button_enter:
            metronome_rest();
            return view_event_result_handled;
        }
        return view_event_result_not_handled;
    }
    return view_event_result_not_handled;
}
#else  //!<#ifdef EVENT_PREVIOUS_VIEW
view_event_result_t view_metronome_state_event(event_param_t const *param)
{
    switch (param->event)
    {
    case event_button_front_long_press:
        display_show(view_metronome, DISP_MODE_NORMAL);
        return view_event_result_handled;
    case event_button_front_press:
        metronome_instance.is_run = !metronome_instance.is_run;
        if (metronome_instance.is_run)
        {
            app_timer_start(metronome_timer_id, APP_TIMER_TICKS(1000 * 60 / metronome_instance.bpm, APP_TIMER_PRESCALER), 0);
            app_timer_start(metronome_timer_second_id, APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER), 0);
        }
        else
        {
            app_timer_stop(metronome_timer_id);
            app_timer_stop(metronome_timer_second_id);
        }
        display_set_update_request(view_metronome_state, 0);
        return view_event_result_handled;
    case event_view_entry:
        if (!metronome_instance.is_init)
        {
            metronome_instance.is_init = true;
            uint32_t err_code = app_timer_create(&metronome_timer_id, APP_TIMER_MODE_REPEATED, &metronome_timer_handle);
            Expects(err_code == NRF_SUCCESS);
            err_code = app_timer_create(&metronome_timer_second_id, APP_TIMER_MODE_REPEATED, &metronome_timer_second_handle);
            Expects(err_code == NRF_SUCCESS);
        }
        metronome_instance.seconds = 0;
        metronome_instance.count = 0;
        metronome_instance.bpm = get_metronome_hz();
        metronome_instance.is_shake = false;
        metronome_instance.is_run = false;
        return view_event_result_handled;
    case event_view_exit:
        app_timer_stop(metronome_timer_id);
        app_timer_stop(metronome_timer_second_id);
        return view_event_result_handled;
    case event_set_metronome:
        metronome_instance.bpm = param->hz;
        if (metronome_instance.is_run)
        {
            app_timer_stop(metronome_timer_id);
            app_timer_stop(metronome_timer_second_id);
            app_timer_start(metronome_timer_id, APP_TIMER_TICKS(1000 * 60 / metronome_instance.bpm, APP_TIMER_PRESCALER), 0);
            app_timer_start(metronome_timer_second_id, APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER), 0);
        }
        display_set_update_request(view_metronome_state, 0);
        return view_event_result_handled;
    }
    return view_event_result_not_handled;
}
#endif //!< #ifdef EVENT_PREVIOUS_VIEW
view_event_result_t view_metronome_event(int view, event_param_t const *param)
{
    switch (view)
    {
    case view_metronome_state:
        return view_metronome_state_event(param);
#ifdef EVENT_PREVIOUS_VIEW
    case view_metronome_set:
        return view_metronome_set_event(param);
#endif
    }
    return view_event_result_not_handled;
}
#endif
